﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text;
using Sharp.Portal.ExtNet.FormField;
using Sharp.Portal.Interface;
using Sharp.Portal.Mvc.Form;

namespace Sharp.Portal.ExtNet.Provider
{
    /// <summary>
    /// Ext.net 表单页
    /// </summary>
    public class FromPage : ITemplateProvider
    {
        /// <summary>
        /// 获取模板
        /// </summary>
        /// <param name="model"></param>
        /// <param name="isMobileDevice"></param>
        /// <returns></returns>
        public string GetTemplate(object model, bool isMobileDevice)
        {
            StringBuilder sb = new StringBuilder();
            Rendering(sb, model);
            return sb.ToString();
        }
        #region 渲染界面

        /// <summary>
        /// 渲染界面
        /// </summary>
        /// <param name="sb"></param>
        /// <param name="iform"></param>
        private void Rendering(StringBuilder sb, object iform)
        {
            var form = ((ISharpForm)iform).UI as ExtSharpFrom;
            sb.AppendFormat("@model {0}\r\n", iform.GetType().FullName);

            sb.AppendLine("@{");
            sb.AppendLine("    var x = Html.X();");
            if (form.Layout != null)
            {
                sb.AppendFormat("Layout = \"{0}\";\r\n", form.Layout.LayoutPath);
            }
            sb.Append("var window = x.Window().Layout(LayoutType.Fit).WindowResponsiveConfig()");
            if (!form.HideTitle)
            {
                sb.Append(".Title(Model.UI.Title)\r\n");
            }

            sb.Append(".Resizable(Model.UI.Resizable).Collapsible(Model.UI.Collapsible).Maximizable(Model.UI.Maximizable).Maximized(Model.UI.Maximized)");
            sb.AppendLine(".CloseAction(CloseAction.Destroy).MinHeight(500)");
            sb.Append(".Width(Model.UI.Width)");

            if (form.Height.HasValue)
            {
                sb.AppendFormat(".Height({0}).AutoScroll(true)", form.Height);
            }

            sb.AppendLine(".Tag(new { refreshGrid = Model.UI.RefreshGrid })");

            sb.AppendLine(";");
            sb.AppendLine("}");
            if (form.Layout != null)
            {
                sb.AppendFormat("@section {0}{{ ", form.Layout.SectionName);
                sb.AppendLine();
            }
            sb.AppendLine("@{");

            form.InitComplete();


            sb.Append("var container = x.Container().Layout(LayoutType.Fit)\r\n");
            sb.AppendLine(".Items(");
            sb.AppendLine("x.FormPanel().Default().AutoScroll(true)");
            sb.AppendLine("                    .Buttons(");
            sb.Append("\r\n                        x.Button().Text(\"提交\").Icon(Icon.Disk).Hidden(Model.UI.CheckReadOnlyForm() || Model.UI.HiddenToolButtons).FormBind(true)");
            sb.AppendLine("                            .DirectEvents(de =>");
            sb.AppendLine("                            {");
            sb.AppendLine("                                de.Click.Before = \"App.Edit.submitReady\";");
            sb.AppendFormat("                                de.Click.Url = Url.Action(\"{0}\");", string.Join("\",\"", form.PostAction.Split(',')));
            sb.AppendLine("                                de.Click.EventMask.ShowMask = true;");
            sb.AppendLine("                                de.Click.EventMask.Msg = \"正在提交...\";");
            sb.AppendLine("                                de.Click.Success = \"App.Edit.PostBackSuccess\";");
            sb.AppendLine("                            }),");
            sb.AppendLine("                        x.Button().Text(\"关闭\").Icon(Icon.Cancel).Hidden(Model.UI.HiddenToolButtons).OnClientClick(\"App.Edit.CloseWindow(this)\")");
            sb.AppendLine("            )");
            if (form.RefreshUrl.IsNotNullOrEmpty())
            {
                sb.AppendLine(".Tag(new { RefreshUrl= @Model.UI.RefreshUrl })");
            }

            if (form.Sections.Count == 1)
            {
                sb.AppendLine(@".Defaults(d => {
        d.Add(new Parameter(""padding"", 4));
        d.Add(new Parameter(""columnWidth"", (Model.UI.OpenWith == OpenWith.Tile2Column || Model.UI.OpenWith == OpenWith.Window2Column)?.5:1));
    })");
                sb.Append(".Layout(LayoutType.Column)");
                sb.Append(".Items(");
                RendingEditing(sb, form);
            }
            else
            {
                sb.Append(".Layout(LayoutType.Fit)");
                sb.Append(".Items(");
                TabRendingEditing(sb, form);
            }

            sb.AppendLine(").CheckFormItemsPermission(this.ModuleCode));");
            sb.AppendLine("}");

            sb.AppendLine(@"@(
                    (Model.UI.OpenWith == OpenWith.Window || Model.UI.OpenWith == OpenWith.Window2Column) ? (object)window.Items(container) : (object)container
            )");


            if (form.Layout != null)
            {
                sb.AppendLine("}");
            }
        }
        private void RendingEditing(StringBuilder sb, ExtSharpFrom form)
        {
            RendingEditing(sb, form, form.Sections[0]);
        }
        private void RendingEditing(StringBuilder sb, ExtSharpFrom form, FormSection formSection)
        {
            var fields = formSection.Fields;

            var fieldLists = new List<string>();

            foreach (var field in fields)
            {
                if (field.HideField) continue;

                if (field.FieldType == FieldType.HiddenInput)
                {
                    fieldLists.Add($"x.HiddenFor(m => m.{field.Name}).AutoId()");
                }
                else if (field.FieldType == FieldType.TextBox)
                {
                    if (field.DataType == DataType.Html)
                    {
                        fieldLists.Add(new HtmlEditorField(field.Name) { LayoutType = form.OpenWith }.Build());
                    }
                    else if (field.DataType == DataType.Upload)
                    {
                        fieldLists.Add(new ImageUploadField(field.Name) { LayoutType = form.OpenWith }.Build());
                    }
                    else if (field.DataType == DataType.Date || field.DataType == DataType.DateTime)
                    {
                        fieldLists.Add(new DateField(field.Name) { LayoutType = form.OpenWith }.Build());
                    }
                    else if (field.DataType == DataType.Time)
                    {
                        fieldLists.Add(new TimeField(field.Name) { LayoutType = form.OpenWith }.Build());
                    }
                    else if (field.DataType == DataType.MultilineText)
                    {
                        fieldLists.Add(new TextAreaField(field.Name) { LayoutType = form.OpenWith }.Build());
                    }
                    else
                    {
                        fieldLists.Add(new TextField(field.Name) { LayoutType = form.OpenWith }.Build());
                    }
                }

                else if (field.FieldType == FieldType.Boolean)
                {
                    fieldLists.Add(
                        new CheckboxField(field.Name) { LayoutType = form.OpenWith }.Build());
                }
                else if (field.FieldType == FieldType.DropDownList)
                {
                    fieldLists.Add(new DropDownListField(
                        field.Name, field.DataSourceName, field.DisplayField, field.ValueField)
                    { LayoutType = form.OpenWith }.Build());
                }
                else if (field.FieldType == FieldType.OrgTreeList || field.FieldType == FieldType.TreeList)
                {
                    fieldLists.Add(new TreeListField(
                        field.Name, field.DataSourceName, field.DisplayField, field.ValueField)
                    { LayoutType = form.OpenWith }.Build());

                }
                else if (field.FieldType == FieldType.MasterData)
                {
                    fieldLists.Add(new MasterDataField(field.Name, field.MasterDataCategory) { LayoutType = form.OpenWith }.Build());
                }
                else if (field.FieldType == FieldType.SelectBox)
                {
                    fieldLists.Add(new SelectBoxField(field.Name)
                    {
                        FieldLabel = field.FieldLabel,
                        LayoutType = form.OpenWith,
                        WindowUrl = field.DataSourceName,
                        DisplayField = field.DisplayField,
                        ValueField = field.ValueField
                    }.Build());
                }
            }



            sb.AppendLine(string.Join(",\r\n", fieldLists.ToArray()));
        }

        private void TabContentEditing(StringBuilder sb, FormSection formSection)
        {
            if (formSection.ItemsFromAction.IsNotNullOrEmpty() && formSection.RouteValues.IsNotNullOrEmpty())
            {
                sb.AppendFormat(".ItemsFromAction(\"{0}\",{1})",
                    string.Join("\",\"", formSection.ItemsFromAction.Split(',')), formSection.RouteValues);
                return;
            }
            else if (formSection.ItemsFromAction.IsNotNullOrEmpty())
            {
                sb.AppendFormat(".ItemsFromAction(\"{0}\")",
                    string.Join("\",\"", formSection.ItemsFromAction.Split(',')));
                return;
            }
        }

        private void TabRendingEditing(StringBuilder sb, ExtSharpFrom form)
        {
            sb.Append("x.TabPanel()");
            sb.AppendLine(".Items(");
            for (var i = 0; i < form.Sections.Count; i++)
            {
                sb.AppendLine("x.Panel()");
                sb.AppendFormat(".Title(\"{0}\")", form.Sections[i].Title);
                sb.AppendLine(@".Defaults(d => {
        d.Add(new Parameter(""padding"", 4));
        d.Add(new Parameter(""columnWidth"", (Model.UI.OpenWith == OpenWith.Tile2Column || Model.UI.OpenWith == OpenWith.Window2Column)?.5:1));
    })");
                if (form.Sections[i].ItemsFromAction.IsNullOrEmpty())
                {
                    sb.Append(".Layout(LayoutType.Column)");
                    sb.AppendLine(".Items(");
                    RendingEditing(sb, form, form.Sections[i]);
                    sb.AppendLine(")");
                }
                else
                {
                    sb.Append(".Region(Region.Center).Layout(LayoutType.Fit)");
                    TabContentEditing(sb, form.Sections[i]);
                }
                if (i < form.Sections.Count - 1)
                {
                    sb.Append(",");
                }
            }
            sb.AppendLine(")");
        }
        #endregion
    }
}
